<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <title>3d台式机小屋</title>
    <style>
        *,
        *::after,
        *::before {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            outline: none;
            font-family: monospace;
        }

        body {
            overflow: hidden;
            background-color: #d2cfc8;
            cursor: grab;
        }

        .webgl,
        #loader {
            position: fixed;
            top: 0;
            left: 0;
        }

        #loader {
            display: grid;
            place-content: center;
            width: 100%;
            height: 100%;
            background-color: #faedcd;
        }
    </style>
</head>

<body>
    <canvas class="webgl"></canvas>
    <div id="loader">
        <h1>Loading</h1>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r124/three.min.js"></script>
    <script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>
    <script src="https://unpkg.com/three@0.126.0/examples/js/controls/OrbitControls.js"></script>
    <script>
        const loading = document.querySelector('#loader');
        const canvas = document.querySelector('.webgl');
        const scene = new THREE.Scene();
        const textureLoader = new THREE.TextureLoader();
        const sizes = { width: window.innerWidth, height: window.innerHeight };
        const camera = new THREE.PerspectiveCamera(
            10,
            sizes.width / sizes.height,
            0.1,
            100
        );
        camera.position.x = 8;
        camera.position.y = 4;
        camera.position.z = 15;
        scene.add(camera);
        const controls = new THREE.OrbitControls(camera, canvas);
        controls.enableDamping = true;
        controls.enableZoom = true;
        controls.enablePan = true;
        controls.minDistance = 21;
        controls.maxDistance = 50;
        controls.minPolarAngle = Math.PI / 5;
        controls.maxPolarAngle = Math.PI / 2;
        const renderer = new THREE.WebGLRenderer({
            canvas: canvas,
            antialias: true,
            alpha: true,
        });
        renderer.setSize(sizes.width, sizes.height);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        renderer.outputEncoding = THREE.sRGBEncoding;
        const bakedTexture = textureLoader.load(
            'https://www.fecoder.cn/code-fun/baked.jpg'
        );
        bakedTexture.flipY = false;
        bakedTexture.encoding = THREE.sRGBEncoding;
        const bakedMaterial = new THREE.MeshBasicMaterial({ map: bakedTexture });
        const loader = new THREE.GLTFLoader();
        loader.load(
            'https://www.fecoder.cn/code-fun/model.glb',
            (gltf) => {
                const model = gltf.scene;
                model.traverse((child) => (child.material = bakedMaterial));
                scene.add(model);
                scene.position.set(0, 0.2, 0);
                loading.style.display = 'none';
            },
            (xhr) => {
                console.log((xhr.loaded / xhr.total) * 100 + '% loaded');
            }
        );
        window.addEventListener('resize', () => {
            sizes.width = window.innerWidth;
            sizes.height = window.innerHeight;
            camera.aspect = sizes.width / sizes.height;
            camera.updateProjectionMatrix();
            renderer.setSize(sizes.width, sizes.height);
            renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        });
        var minPan = new THREE.Vector3(-2, -0.5, -2);
        var maxPan = new THREE.Vector3(2, 0.5, 2);
        const tick = () => {
            controls.update();
            controls.target.clamp(minPan, maxPan);
            renderer.render(scene, camera);
            window.requestAnimationFrame(tick);
        };
        tick();
    </script>
</body>

</html>